home *** CD-ROM | disk | FTP | other *** search
/ MacFormat España 15 / macformat_15.iso / Shareware Internet / Utilidades / PRAM-Reader 1.1.2 / Developers / PRAM-Reader.p next >
Text File  |  1995-03-14  |  14KB  |  618 lines

  1. {Source Code of PRAM-reader}
  2.  
  3. {PRAM-Reader is developed by}
  4. {  Matthias Wuttke}
  5. {  Hilterweg 14}
  6. {  33803 Steinhagen}
  7. {  GERMANY}
  8. {  Internet: wuttke@stein.teuto.de }
  9.  
  10. { You may use this code and pieces of it freely if }
  11. { A) you send me a copy of your program }
  12. { B) you writes my name in your "About..."-box }
  13.  
  14. { If you find any errors, please don't give out any versions, instead of doing this, report }
  15. { me the error and I will fix it. It's important not to have much different versions. }
  16.  
  17. { Compiled with THINK Pascal 4.0.2. To use it with MPW Pascal, insert in the Initialize-Procedure at the end of this file }
  18. { calls to Toolbox routines to init the different managers. }
  19.  
  20. PROGRAM PRAMReader;
  21.     CONST
  22.         creator = 'PRRD';            { Creator of the application and its files }
  23.         filetype = 'PRam';            { Type of PRAM-Content files }
  24.  
  25. { Dialog-IDs }
  26.         rAboutDialog = 128;
  27.         rMainWindow = 129;
  28.  
  29. { Menus }
  30.         rMenuBar = 128;
  31.  
  32.         mApple = 128;
  33.         mFile = 129;
  34.         mEdit = 130;
  35.  
  36. { Apple-Menu }
  37.         iAbout = 1;
  38.  
  39. { File-Menu }
  40.         iReadPRAM = 1;
  41.         iWritePRAM = 2;
  42.         iQuit = 4;
  43.  
  44. { Edit-Menu }
  45.         iUndo = 1;
  46.         iCut = 3;
  47.         iCopy = 4;
  48.         iPaste = 5;
  49.         iClear = 6;
  50.  
  51. { PRAM information }
  52.         oldPRAMSize = 20;        { size of the "old" PRAM (see IM: OS Utils) }
  53.         extPRAMSize = 256;    { size of the extended PRAM ("xPRAM") }
  54.  
  55. { Traps for reading and writing the xPRAM *undocumented* }
  56.         _ReadXPRam = $A051;
  57.         _WriteXPRam = $A052;
  58.  
  59. { Offsets of the two blocks we write into the xPRAM }
  60.         parm1Off = 104;
  61.         parm1Len = 12;
  62.  
  63.         parm2Off = 116;
  64.         parm2Len = 138;
  65.  
  66.     TYPE
  67.         UInt = Integer;        { declared as -32767..32768, but really 0..65535 }
  68.  
  69.         PRamSettings = RECORD        { this record is stored in PRAM-content files }
  70.                 PRam: SysParmType;        { "old" PRAM (see IM: OS Utils) }
  71.  
  72.                 XPRam: PACKED RECORD        { the extended PRAM }
  73.                         CASE Integer OF
  74.                             0: (
  75.                                     body: PACKED ARRAY[0..255] OF Char;        { raw data of xPRAM }
  76.                             );
  77.                             1: (
  78.                                     layout: PACKED RECORD
  79. { clock settings, etc. }
  80.                                             dummy1: PACKED ARRAY[0..51] OF UInt;         { +     0 }
  81. { the following two do we write. For a xPRAM-map mail me. }
  82.                                             parm1: PACKED ARRAY[0..5] OF UInt;            { + 104 }
  83.                                             parm2: PACKED ARRAY[0..68] OF UInt;        { + 116 }
  84. { unused, can't be written by _WriteXPRam because of a bug  in this trap }
  85.                                             dummy2: UInt;                                            { + 254 }
  86.                                         END;                                                        { + 256 }
  87.                             );
  88.                     END;
  89.             END;
  90.         PRamSettingsPtr = ^PRamSettings;
  91.  
  92.     VAR
  93.         gEvent: EventRecord;
  94.         gGotEvent, gQuit: boolean;
  95.         mainDialog: DialogPtr;
  96.  
  97.  
  98. { ****** READING AND WRITING FROM/TO THE (x)PRAM ****** }
  99.  
  100.  
  101.     PROCEDURE ReadXPRam (where: Ptr; size: Integer);        { reads size bytes of the xPRAM to where }
  102.     INLINE
  103.         $4280,    { CLR.L D0 }
  104.         $301F,     { MOVE.W (A7)+, D0 }
  105.         $4840,     { SWAP D0 }
  106.         $205F,     { MOVEA.L (A7)+, A0 }
  107.         _ReadXPRam;
  108.  
  109.     PROCEDURE WriteXPRam (where: Ptr; offset: Integer; size: Integer);
  110. { writes size bytes from where to the xPRAM beginning with offset }
  111.     INLINE
  112.         $201F,     { MOVE.L (A7)+, D0 }
  113.         $205F,     { MOVEA.L (A7)+, A0 }
  114.         _WriteXPRam;
  115.  
  116.     FUNCTION ReadPRamSettingsFromFile (refNum: Integer; VAR settings: PRamSettingsPtr): OSErr;
  117. { reads a PRamSettingsPtr from a PRAM-content file. settings is allocated. }
  118.         VAR
  119.             len: LongInt;
  120.     BEGIN
  121.         len := oldPRamSize + extPRamSize;        { size of block to read }
  122.         Ptr(settings) := NewPtrClear(len);
  123.         IF settings = NIL THEN
  124.             ReadPRamSettingsFromFile := memFullErr
  125.         ELSE
  126.             ReadPRamSettingsFromFile := FSRead(refNum, len, Ptr(settings));        { read block }
  127.     END;
  128.  
  129.     FUNCTION WritePRamSettingsToFile (refNum: Integer; settings: PRamSettingsPtr): OSErr;
  130. { writes a PRamSettingsPtr to a PRAM-content file. "settings" has to be valid}
  131.         VAR
  132.             len: LongInt;
  133.     BEGIN
  134.         len := oldPRamSize + extPRamSize;
  135.         WritePRamSettingsToFile := FSWrite(refNum, len, Ptr(settings));
  136.     END;
  137.  
  138.     FUNCTION GetPRamSettings (VAR p: PRamSettingsPtr): OSErr;
  139. { creates a new PRamSettingsPtr and fills it with the current content of the PRAM and the xPRAM }
  140.     BEGIN
  141.         Ptr(p) := NewPtrClear(oldPRAMSize + extPRAMSize);        { allocate memory }
  142.         IF p <> NIL THEN
  143.             BEGIN
  144.                 p^.PRam := GetSysPPtr^;        { copy "old" PRAM (see IM: OS Utils) }
  145.                 IF p^.PRam.valid <> $A8 THEN        { PRAM is only valid if first byte is $A8 }
  146.                     GetPRamSettings := badFormat
  147.                 ELSE
  148.                     BEGIN
  149.                         ReadXPRam(@p^.xpram.body, extPRAMSize);        { reads the xPRAM }
  150.                         GetPRamSettings := noErr;
  151.                     END;
  152.             END
  153.         ELSE
  154.             GetPRamSettings := memFullErr;
  155.     END;
  156.  
  157.     PROCEDURE SetPRam (settings: PRamSettingsPtr);
  158. { sets the PRAM and the xPRAM to the settings specified in "settings". "settings" has to be allocated. }
  159.         VAR
  160.             err: OSErr;
  161.     BEGIN
  162. { write "old" PRAM back (see IM: OS Utils) }
  163.         GetSysPPtr^ := settings^.PRam;
  164.         err := WriteParam;
  165.  
  166. { write xPRAM back }
  167.         WriteXPRam(@settings^.xpram.layout.parm1, parm1Off, parm1Len);
  168.         WriteXPRam(@settings^.xpram.layout.parm2, parm2Off, parm2Len);
  169.     END;
  170.  
  171.  
  172. { ****** APPLICATION EVENT HANDLING CODE ******* }
  173.  
  174.     PROCEDURE DoError (i: Integer);
  175. { displays an alert with the error message with the index i }
  176.         VAR
  177.             str: Str255;
  178.             itemHit: Integer;
  179.     BEGIN
  180.         GetIndString(str, 128, i);
  181.         ParamText(str, '', '', '');
  182.         itemHit := Alert(256, NIL);
  183.     END;
  184.  
  185.     PROCEDURE DoReadPRAM;
  186. { reads out the PRAM and writes it to a disk file. }
  187.         VAR
  188.             r: SFReply;
  189.             pt: Point;
  190.             err: OSErr;
  191.             refnum: Integer;
  192.             p: PRamSettingsPtr;
  193.  
  194.         PROCEDURE Check (ind: Integer);    { checks if an error occured }
  195.         BEGIN
  196.             IF err <> noErr THEN
  197.                 BEGIN
  198.                     IF refnum <> 0 THEN
  199.                         err := FSClose(refnum);
  200.                     IF p <> NIL THEN
  201.                         DisposePtr(Ptr(p));
  202.                     DoError(ind);
  203.                     Exit(DoReadPRAM);
  204.                 END;
  205.         END;
  206.  
  207.     BEGIN
  208. { asking for the file name (I know, I should use the new routines (FSp...)) }
  209.         p := NIL;
  210.         SetPt(pt, 90, 90);
  211.         refnum := 0;
  212.         SFPutFile(pt, 'File name for PRAM-dump:', 'PRAM-Content', NIL, r);
  213.         IF NOT r.good THEN
  214.             exit(DoReadPRAM);
  215.  
  216. { creating the file }
  217.         err := FSDelete(r.fName, r.vRefNum);
  218.         err := Create(r.fName, r.vRefNum, creator, filetype);
  219.         Check(4);
  220.  
  221. { opening it }
  222.         err := FSOpen(r.fName, r.vRefNum, refnum);
  223.         Check(4);
  224.  
  225. { get a new PRamSettingsPtr }
  226.         err := GetPRamSettings(p);
  227.         IF err = badFormat THEN
  228.             Check(2)
  229.         ELSE IF err = memFullErr THEN
  230.             Check(6);
  231.         Check(4);
  232.  
  233.  
  234. { write it to a file }
  235.         err := WritePRamSettingsToFile(refNum, p);
  236.         Check(4);
  237.  
  238. { clean up }
  239.         err := FSClose(refnum);
  240.         Check(4);
  241.  
  242.         DisposePtr(Ptr(p));
  243.     END;
  244.  
  245.     PROCEDURE DoWritePRAM;
  246. { writes the content of a PRAM-content file to the PRAM }
  247.         VAR
  248.             pt: Point;
  249.             tl: SFTypeList;
  250.             r: SFReply;
  251.             err: OSErr;
  252.             refnum: Integer;
  253.             len: LongInt;
  254.             p: PRamSettingsPtr;
  255.  
  256.         PROCEDURE Check (ind: Integer);    { checks if an error occured }
  257.         BEGIN
  258.             IF err <> noErr THEN
  259.                 BEGIN
  260.                     IF refnum <> 0 THEN
  261.                         err := FSClose(refnum);
  262.                     IF p <> NIL THEN
  263.                         DisposePtr(Ptr(p));
  264.                     DoError(ind);
  265.                     Exit(DoWritePRAM);
  266.                 END;
  267.         END;
  268.  
  269.     BEGIN
  270. { ask for file }
  271.         p := NIL;
  272.         SetPt(pt, 90, 90);
  273.         tl[0] := filetype;
  274.  
  275.         SFGetFile(pt, 'Select PRAM-dump:', NIL, 1, tl, NIL, r);
  276.         IF NOT r.good THEN
  277.             Exit(DoWritePRAM);
  278.  
  279. { open it }
  280.         err := FSOpen(r.fName, r.vRefnum, refnum);
  281.         Check(3);
  282.  
  283. { get its length }
  284.         err := GetEOF(refnum, len);
  285.         Check(3);
  286.         IF len = 20 THEN    { old version error }
  287.             BEGIN
  288.                 err := -1;
  289.                 Check(5);
  290.             END
  291.         ELSE IF len <> oldPRamSize + extPRamSize THEN    { bad file error }
  292.             BEGIN
  293.                 err := -1;
  294.                 Check(1);
  295.             END;
  296.  
  297. { rewrite it }
  298.         err := ReadPRamSettingsFromFile(refNum, p);
  299.         IF err = memFullErr THEN
  300.             Check(6);    { not enough memory }
  301.         Check(3);    { bad format (no $A8)? }
  302.  
  303. { close file }
  304.         err := FSClose(refnum);
  305.         Check(3);
  306.  
  307. { Are you sure... dialogue }
  308.         IF Alert(257, NIL) = 2 THEN
  309.             SetPRam(p);        { set the PRAM to its old content }
  310.  
  311. { clean up }
  312.         DisposePtr(Ptr(p));
  313.     END;
  314.  
  315.     PROCEDURE DoAbout;
  316. { displays About...-dialogue }
  317.         VAR
  318.             itemHit: INTEGER;
  319.             theDialog: DialogPtr;
  320.     BEGIN
  321.         theDialog := GetNewDialog(rAboutDialog, NIL, WindowPtr(-1));
  322.         REPEAT
  323.             ModalDialog(NIL, itemHit)
  324.         UNTIL (itemHit = 1);
  325.         DisposeDialog(theDialog);
  326.     END;
  327.  
  328.     PROCEDURE DoAppleMenu (menuItem: INTEGER);
  329.         VAR
  330.             daRefNum: INTEGER;
  331.             daName: Str255;
  332.     BEGIN
  333.         CASE menuItem OF
  334.             iAbout: 
  335.                 DoAbout;
  336.             OTHERWISE
  337.                 BEGIN
  338.                     GetItem(GetMHandle(mApple), menuItem, daName);
  339.                     daRefNum := OpenDeskAcc(daName);
  340.                 END;
  341.         END;
  342.     END;
  343.  
  344.     FUNCTION IsDAWindow (theWindow: WindowPtr): INTEGER;
  345.         VAR
  346.             daRefNum: INTEGER;
  347.     BEGIN
  348.         daRefNum := WindowPeek(theWindow)^.windowKind;
  349.         IF daRefNum < 0 THEN
  350.             IsDAWindow := daRefNum
  351.         ELSE
  352.             IsDAWindow := 0;
  353.     END;
  354.  
  355.     PROCEDURE DoClose;
  356.         VAR
  357.             theWindow: WindowPtr;
  358.             daRefNum: Integer;
  359.     BEGIN
  360.         theWindow := FrontWindow;
  361.         daRefNum := IsDAWindow(theWindow);
  362.         IF daRefNum < 0 THEN
  363.             BEGIN
  364.                 CloseDeskAcc(daRefNum);
  365.                 Exit(DoClose);
  366.             END;
  367.         IF theWindow = mainDialog THEN
  368.             BEGIN
  369.                 DisposeDialog(mainDialog);
  370.                 gQuit := true;
  371.             END
  372.         ELSE
  373.             DisposeWindow(theWindow);    { unknown window }
  374.     END;
  375.  
  376.     PROCEDURE DoQuit;
  377.     BEGIN
  378.         gQuit := true;
  379.         WHILE FrontWindow <> NIL DO
  380.             DoClose;
  381.     END;
  382.  
  383.     PROCEDURE DoFileMenu (menuItem: INTEGER);
  384.     BEGIN
  385.         CASE menuItem OF
  386.             iReadPRAM: 
  387.                 DoReadPRAM;
  388.             iWritePRAM: 
  389.                 DoWritePRAM;
  390.             iQuit: 
  391.                 DoQuit;
  392.             OTHERWISE
  393.                 ;
  394.         END;
  395.     END;
  396.  
  397.     PROCEDURE DoMenuCommand (choice: LONGINT);
  398.         VAR
  399.             menuID, menuItem: INTEGER;
  400.     BEGIN
  401.         menuID := HiWord(choice);
  402.         menuItem := LoWord(choice);
  403.         CASE menuID OF
  404.             mApple: 
  405.                 DoAppleMenu(menuItem);
  406.             mFile: 
  407.                 DoFileMenu(menuItem);
  408.             mEdit: 
  409.                 IF NOT SystemEdit(menuItem - 1) THEN
  410.                     SysBeep(1);
  411.         END;
  412.         HiliteMenu(0);
  413.     END;
  414.  
  415.     PROCEDURE AdjustMenus;
  416.         VAR
  417.             theMenu: MenuHandle;
  418.             i: Integer;
  419.     BEGIN
  420.         theMenu := GetMHandle(mEdit);
  421.         IF ISDaWindow(FrontWindow) < 0 THEN    { enable all items if DA in front }
  422.             FOR i := 0 TO iClear DO
  423.                 EnableItem(theMenu, i)
  424.         ELSE                                            { else disable all }
  425.             FOR i := 0 TO iClear DO
  426.                 DisableItem(theMenu, i);
  427.     END;
  428.  
  429.     PROCEDURE MakeMenus;
  430.         VAR
  431.             menuBar: Handle;
  432.     BEGIN
  433.         menuBar := GetNewMBar(rMenuBar);
  434.         SetMenuBar(menuBar);
  435.         DisposHandle(menuBar);
  436.         AddResMenu(GetMHandle(mApple), 'DRVR');
  437.         DrawMenuBar;
  438.     END;
  439.  
  440.     FUNCTION GetItemRect (d: DialogPtr; i: Integer): Rect;
  441. { returns the rectangle of item i of dialog d }
  442.         VAR
  443.             iKind: Integer;
  444.             iHandle: Handle;
  445.             iRect: Rect;
  446.     BEGIN
  447.         GetDItem(d, i, iKind, iHandle, iRect);
  448.         GetItemRect := iRect;
  449.     END;
  450.  
  451.     PROCEDURE DoContentClick (theWindow: WindowPtr);
  452. { checks if user hit button }
  453.         VAR
  454.             locMouse: Point;
  455.             i, itemHit: Integer;
  456.             r: Rect;
  457.  
  458.     BEGIN
  459.         IF theWindow <> FrontWindow THEN
  460.             BEGIN
  461.                 SelectWindow(theWindow);
  462.                 Exit(DoContentClick);
  463.             END;
  464.  
  465.         SetPort(theWindow);
  466.         locMouse := gEvent.where;
  467.         GlobalToLocal(locMouse);
  468.         IF theWindow <> mainDialog THEN
  469.             Exit(DoContentClick);
  470.  
  471.         itemHit := -1;
  472.         FOR i := 1 TO 4 DO
  473.             IF PtInRect(locMouse, GetItemRect(mainDialog, i)) THEN
  474.                 itemHit := i;
  475.  
  476.         CASE itemHit OF
  477.             1: 
  478.                 DoReadPRAM;
  479.             2: 
  480.                 DoWritePRAM;
  481.             3: 
  482.                 DoAbout;
  483.             4: 
  484.                 DoQuit;
  485.             -1: 
  486.                 SysBeep(1);    { don't hit a button }
  487.         END;
  488.     END;
  489.  
  490.     PROCEDURE DoDragWindow (theWindow: WindowPtr);
  491.     BEGIN
  492.         IF theWindow <> FrontWindow THEN
  493.             SelectWindow(theWindow);
  494.         SetPort(theWindow);
  495.         DragWindow(theWindow, gEvent.where, screenBits.bounds);
  496.     END;
  497.  
  498.     PROCEDURE DoCloseWindow (theWindow: WindowPtr);
  499.     BEGIN
  500.         IF TrackGoAway(theWindow, gEvent.where) THEN
  501.             DoClose;
  502.     END;
  503.  
  504.     PROCEDURE DoMouseDown;
  505.         VAR
  506.             part: INTEGER;
  507.             theWindow: WindowPtr;
  508.     BEGIN
  509.         part := FindWindow(gEvent.where, theWindow);
  510.         CASE part OF
  511.             inSysWindow: 
  512.                 SystemClick(gEvent, theWindow);
  513.             inContent: 
  514.                 DoContentClick(theWindow);
  515.             inDrag: 
  516.                 DoDragWindow(theWindow);
  517.             inGoAway: 
  518.                 DoCloseWindow(theWindow);
  519.             inMenuBar: 
  520.                 BEGIN
  521.                     AdjustMenus;
  522.                     DoMenuCommand(MenuSelect(gEvent.where));
  523.                 END;
  524.         END;
  525.     END;
  526.  
  527.     PROCEDURE DoKeyDown;
  528.         VAR
  529.             key: char;
  530.     BEGIN
  531.         IF BitAnd(gEvent.modifiers, cmdKey) = cmdKey THEN
  532.             BEGIN
  533.                 key := char(BitAnd(gEvent.message, charCodeMask));
  534.                 AdjustMenus;
  535.                 DoMenuCommand(MenuKey(key));
  536.             END;
  537.     END;
  538.  
  539.     PROCEDURE DoUpdate;
  540.         VAR
  541.             theWindow: WindowPtr;
  542.     BEGIN
  543.         theWindow := WindowPtr(gEvent.message);
  544.         BeginUpdate(theWindow);
  545.         SetPort(theWindow);
  546.         EraseRect(theWindow^.portRect);
  547.         IF theWindow = mainDialog THEN
  548.             BEGIN
  549.                 DrawDialog(mainDialog);    { the Dialog Manager does the work for us }
  550.             END;
  551.         EndUpdate(theWindow);
  552.     END;
  553.  
  554.     PROCEDURE DoActivate;
  555.     BEGIN
  556. { only one window in this app, if switching, it is hided }
  557.     END;
  558.  
  559.     PROCEDURE DoOsEvt;
  560.     BEGIN
  561.         IF BAnd(BRotL(gEvent.message, 8), $FF) = suspendResumeMessage THEN
  562.             IF BAnd(gEvent.message, resumeFlag) <> 0 THEN
  563.                 BEGIN
  564.                     ShowWindow(mainDialog);        { show window if switching to PRAM-Reader }
  565.                 END
  566.             ELSE
  567.                 BEGIN
  568.                     HideWindow(mainDialog);        { hide window if switching to the background }
  569.                 END;
  570.     END;
  571.  
  572.     PROCEDURE DoEvent;
  573.     BEGIN
  574.         CASE gEvent.what OF
  575.             mouseDown: 
  576.                 DoMouseDown;
  577.             keyDown: 
  578.                 DoKeyDown;
  579.             autoKey: 
  580.                 DoKeyDown;
  581.             updateEvt: 
  582.                 DoUpdate;
  583.             activateEvt: 
  584.                 DoActivate;
  585.             osEvt: 
  586.                 DoOsEvt;
  587.         END;
  588.     END;
  589.  
  590. { ****** INTIALISATION OF PRAM-READER ****** }
  591.  
  592.     PROCEDURE OpenMainWindow;
  593.         VAR
  594.             r: Rect;
  595.             pt: Point;
  596.     BEGIN
  597.         mainDialog := GetNewDialog(rMainWindow, NIL, WindowPtr(-1));
  598.     END;
  599.  
  600.     PROCEDURE Initialize;
  601.     BEGIN
  602. { don't need to init toolbox because THINK Pascal does this for us }
  603.         SetCursor(arrow);
  604.         gQuit := false;
  605.         MakeMenus;
  606.         OpenMainWindow;
  607.     END;
  608.  
  609. { ****** MAIN EVENT LOOP ****** }
  610. BEGIN
  611.     Initialize;
  612.     WHILE NOT gQuit DO
  613.         BEGIN
  614.             gGotEvent := WaitNextEvent(everyEvent, gEvent, 15, NIL);
  615.             IF gGotEvent THEN
  616.                 DoEvent;
  617.         END;
  618. END.